package org.bdware.repository.handler;

import org.apache.log4j.Logger;
import org.bdware.doip.core.doipMessage.DoipMessage;
import org.bdware.doip.core.doipMessage.DoipResponseCode;
import org.bdware.doip.core.model.digitalObject.DigitalObject;
import org.bdware.doip.core.model.digitalObject.DoType;
import org.bdware.doip.core.model.digitalObject.Element;
import org.bdware.doip.endpoint.doipServer.DoipServiceInfo;
import org.bdware.doip.endpoint.doipServer.RepositoryHandlerBase;

import java.io.*;
import java.text.DecimalFormat;
import java.util.HashMap;

public class StreamRepositoryHandler extends RepositoryHandlerBase {

    static Logger logger = Logger.getLogger(StreamRepositoryHandler.class);
    final String musicDO = "86.5000.470/do.localMp3Test_bdw";
    final String cpuDO = "86.5000.470/do.ZzdUNC9SAU_bdw";
    //    final String streamingDO = "86.5000.470/do.Mp3Test";
    final String filePath = "/Users/blesser/Documents/Work_Work/Java/BDWareDOIP/netty-doserver/src/test/file/JingleBells.mp3";
    //    final String filePath = "/home/dev/DOIP/RTPRepository/files/JingleBells.mp3";

    HashMap<Integer,BufferedInputStream> streamInProcess;

    public StreamRepositoryHandler(DoipServiceInfo info) {
        super(info);
    }

    @Override
    public DoipMessage handleHello(DoipMessage request) {
        return replyDoipServiceInfo(request);
    }

    @Override
    public DoipMessage handleListOps(DoipMessage request) {
        return null;
    }

    @Override
    public DoipMessage handleCreate(DoipMessage request) {
        return null;
    }

    @Override
    public DoipMessage handleUpdate(DoipMessage request) {
        return null;
    }

    @Override
    public DoipMessage handleDelete(DoipMessage request) {
        return null;
    }

    @Override
    public DoipMessage handleRetrieve(DoipMessage request) {
        logger.debug("handleRetrieve start: ");
        if (request.header.parameters.id.equals(cpuDO)){
            //获取本地实时CPU使用率
            double cpusage = CPUMonitorCalc.getInstance().getProcessCpu() * 100;
            DecimalFormat df = new DecimalFormat("#.00");
            String usageStr = df.format(cpusage) + "%";
            logger.info("local cpu usage: " + usageStr);
            if(request.header.parameters.attributes==null || request.header.parameters.attributes.get("action") == null){
                DigitalObject cDO = new DigitalObject(cpuDO, DoType.DO);
                Element cpuUsage = new Element("usage","string/stream");
                cpuUsage.setData((usageStr).getBytes());
                cDO.addElements(cpuUsage);
                cDO.addAttribute("description","local CPU Usage.");
                return replyDO(request,cDO);
            }
            return replyString(request,usageStr);
        }else if (request.header.parameters.id.equals(musicDO)){
            byte[] fileBytes = new byte[800];
            if(streamInProcess.containsKey(request.requestID)){
                BufferedInputStream buffer = streamInProcess.get(request.requestID);
                try {
                    buffer.read(fileBytes);
                    logger.debug("continue mp3 file, length: " + fileBytes.length);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                streamInProcess.put(request.requestID,buffer);
            }else{
                File music;
                music = new File(filePath);
                try {
                    BufferedInputStream buffer = new BufferedInputStream(new FileInputStream(music));
                    buffer.read(fileBytes);
                    streamInProcess.put(request.requestID,buffer);
                    logger.debug("start a new Stream: " + fileBytes.length);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    return replyStringWithStatus(request, "file not found", DoipResponseCode.DoNotFound);
                } catch (IOException e) {
                    e.printStackTrace();
                    return replyStringWithStatus(request, "read file error", DoipResponseCode.MoreThanOneErrors);
                }
            }
            return replyBytes(request,fileBytes);
        }
        else{
            return replyStringWithStatus(request, "not exists", DoipResponseCode.DoNotFound);
        }
    }
}
